#ifndef _SCENCE_HPP_20120625
#define _SCENCE_HPP_20120625

#include <assert.h>
#include <ext/hash_map>

#include "base.hpp"

#include "singleton.hpp"
#include "acceptor_manager.hpp"
#include "processor.hpp"
#include "connection.hpp"

#include "timer.hpp"

#include "cmd_parser.hpp"
#include "confsvr_cmd.hpp"
#include "scence_cmd.hpp"

#include "player.hpp"
#include "player_mgr.hpp"

#include "table.hpp"
#include "basesvr.hpp"

using namespace mina;
using namespace cmd;

typedef SSScenceRes ScenceConf;

class Scence : public BaseSvr, public Singleton<Scence>
{
	public :
		friend class Singleton<Scence>;

	public :
		typedef AcceptorManager Reactor;

	public :
		virtual ~Scence() { finish(); }

		// should implement those function
		virtual int impl_init();
		virtual int process();
		virtual int reload();
		virtual int finish();

		void report_area();

		template <typename _Msg>
		int handle(Connection & conn, _Msg & msg);
		
		Reactor * reactor()               { return _reactor; }

		int send_to_gateway(Connection & conn, void * data)  
		{ 
			return _reactor->send_data(conn.conn_id(), data); 
		}

	public :
		Reactor         *      _reactor;

		ScenceConf             _conf;

		static Processor<Scence>  _confsvr_processor;
		static Processor<Scence>  _gateway_processor;

		CmdParser                 _parser;

		DECL_LOGGER(logger);
};

template <typename _Msg>
int Scence::handle(Connection & conn, _Msg & msg)
{
	Player * player = PlayerMgr::instance().find_player(msg._rid);

	if (NULL == player)
	{
		LOG4CPLUS_ERROR(logger, "not found player. rid: " << msg._rid
							<< ", cmd_0: " << (int)msg._cmd_0
							<< ", cmd_1: " << (int)msg._cmd_1);
		// @TODO response not found player
		return 0;
	}

	const Position & position = player->_role_b._position;

	Table * table = Area::instance().find_table(position._room_id, position._table_id);

	if (NULL == table)
	{
		LOG4CPLUS_ERROR(logger, "not found table. rid: " << msg._rid
								<< ", cmd_0: " << (int)msg._cmd_0
								<< ", cmd_1: " << (int)msg._cmd_1);
		// @TODO response not found table
		return 0;
	}

	int ret = table->handle(player, conn, (void*)&msg);

	return ret;
}

#endif

